import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;

public class Pin extends MapObject
{
    private static final long serialVersionUID = 1284625059544055225L;
    /**
     * The default size of a Pin
     */
    public static final double PIN_SIZE_DEFAULT = 13;
    private double pinSize = PIN_SIZE_DEFAULT;
    private double horizontalOffset;
    private double verticalOffset;
    private Shape icons[];
    private int shapeChooserChoice = 0;

    /**
     * Creates a new Pin object
     * 
     * @param map
     *            - the map the Pin is contained in
     * @param containingPanel
     *            - the MapPanel object that contains the map
     */
    public Pin(Map map, MapPanel containingPanel)
    {
	super(map, containingPanel);
	this.icons = new Shape[] { new Ellipse2D.Double(this.xCoord - this.pinSize / 2, this.yCoord - this.pinSize / 2, this.pinSize, this.pinSize), new Rectangle2D.Double(this.xCoord - this.pinSize / 2, this.yCoord - this.pinSize / 2, this.pinSize, this.pinSize) };

	// default values for the Pin
	this.color = Color.RED;
	this.icon = this.icons[0];

    }

    // copy constructor
    public Pin(Pin pin)
    {
	super(pin);
	this.pinSize = pin.pinSize;
	this.horizontalOffset = pin.horizontalOffset;
	this.verticalOffset = pin.verticalOffset;
	this.icons = pin.icons.clone();
	this.shapeChooserChoice = pin.shapeChooserChoice;
    }

    @Override
    public void setLoc(int x, int y)
    {
	this.xCoord = (int) (x - (this.pinSize / 2));
	this.yCoord = (int) (y - (this.pinSize / 2));

	this.horizontalOffset =  ((x - this.map.getStartXCoord()) / this.map.getZoomLevel()) - (this.pinSize / 2);
	this.verticalOffset =  ((y - this.map.getStartYCoord()) / this.map.getZoomLevel()) - (this.pinSize / 2);
    }

    @Override
    public void displayCreatePrompt(boolean isEditing)
    {
	
	JDialog creationWindow = new JDialog((JDialog) null, "Enter " + this.getClass().getName() + " Information", true);
	creationWindow.setResizable(false);

	JPanel contentPanel = new JPanel();
	contentPanel.setPreferredSize(new Dimension(400, 300));
	contentPanel.setFocusable(false);

	contentPanel.setLayout(new GridBagLayout());
	GridBagConstraints constraints = new GridBagConstraints();
	constraints.fill = GridBagConstraints.HORIZONTAL;

	JLabel nameLabel = new JLabel("name: ");
	JLabel infoLabel = new JLabel("Info: ");
	JLabel transparencyLabel = new JLabel("Transparency: ");

	JTextArea nameInfo = new JTextArea();
	nameInfo.setText(this.name);
	nameInfo.addFocusListener(new InstructorUI.ClearTextListener(nameInfo.getText()));
	JScrollPane nameScrollArea = new JScrollPane();
	nameScrollArea.getViewport().add(nameInfo);

	JButton objectInfo = new JButton("Edit Info");
	objectInfo.addActionListener(new ObjectInfoWindowListener());

	String[] shapes = new String[] { "Circle", "Square" };
	JComboBox shapeList = new JComboBox(shapes);
	shapeList.setSelectedIndex(this.shapeChooserChoice);
	shapeList.addActionListener(new IconChooserListener());

	JButton colorChooser = new JButton("Color:");
	colorChooser.addActionListener(new ColorButtonListener());

	JSlider transparency = new JSlider(SwingConstants.HORIZONTAL, 0, 255, this.transperancy);
	transparency.addChangeListener(new SliderTransperancyListener());
	transparency.setMajorTickSpacing(transparency.getMaximum());
	transparency.setPaintLabels(true);

	JButton addLink = new JButton("Add Hyperlink");
	addLink.addActionListener(new AddHyperlinkWindowListener());

	JButton removeLink = new JButton("Remove Hyperlink");
	removeLink.addActionListener(new RemoveHyperlinkWindowListener());

	JButton save = new JButton("Save");
	save.addActionListener(new CreatePromptSaveListener(creationWindow, nameInfo));

	JButton delete = new JButton("Delete");
	delete.addActionListener(new DeleteObjectListener(creationWindow));

	// GridBagLayout code sucks
	constraints.weightx = .1;
	constraints.weighty = .25;
	constraints.gridx = 0;
	constraints.gridy = 0;
	constraints.ipady = 10;
	contentPanel.add(nameLabel, constraints);

	constraints.gridx = 1;
	constraints.gridy = 0;
	constraints.anchor = GridBagConstraints.LINE_START;
	contentPanel.add(nameScrollArea, constraints);

	constraints.gridx = 0;
	constraints.gridy = 1;
	contentPanel.add(infoLabel, constraints);

	constraints.gridx = 1;
	constraints.gridy = 1;
	constraints.ipady = 100;
	contentPanel.add(objectInfo, constraints);

	constraints.gridx = 0;
	constraints.gridy = 2;
	constraints.ipady = 10;
	contentPanel.add(shapeList, constraints);

	constraints.gridx = 1;
	constraints.gridy = 2;
	contentPanel.add(colorChooser, constraints);

	constraints.gridx = 0;
	constraints.gridy = 3;
	contentPanel.add(transparencyLabel, constraints);

	constraints.gridx = 1;
	constraints.gridy = 3;
	contentPanel.add(transparency, constraints);

	constraints.gridx = 0;
	constraints.gridy = 4;
	contentPanel.add(addLink, constraints);

	constraints.gridx = 1;
	constraints.gridy = 4;
	contentPanel.add(removeLink, constraints);

	constraints.gridx = 0;
	constraints.gridy = 5;
	// if the window is in editing mode, then we want the save button to be
	// smaller to make room for the delete button
	constraints.gridwidth = isEditing ? 1 : 2;
	constraints.anchor = GridBagConstraints.PAGE_END;
	contentPanel.add(save, constraints);
	
	creationWindow.add(contentPanel);

	if (isEditing)
	{
	    constraints.gridx = 1;
	    constraints.gridy = 5;
	    contentPanel.add(delete, constraints);
	    creationWindow.add(contentPanel);
	}

	creationWindow.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
	creationWindow.addWindowListener(new WindowCloseListerner());
	creationWindow.pack();

	save.requestFocusInWindow();
	// setting the relative location to null sets the location to the center of the screen
	creationWindow.setLocationRelativeTo(null);
	creationWindow.setVisible(true);
    }

    @Override
    public void scaleCoords()
    {
	this.xCoord = (int) (this.map.getStartXCoord() + (this.horizontalOffset * this.map.getZoomLevel()));
	this.yCoord = (int) (this.map.getStartYCoord() + (this.verticalOffset * this.map.getZoomLevel()));

	this.pinSize = PIN_SIZE_DEFAULT * this.map.getZoomLevel();

	((RectangularShape) this.icon).setFrame(this.xCoord, this.yCoord, this.pinSize, this.pinSize);
    }

    @Override
    public String toString()
    {
	return this.getClass() + "(x: " + this.xCoord + ", y: " + this.yCoord + ", size: " + this.pinSize + ")";
    }

    @Override
    public Pin copy()
    {
	return new Pin(this);
    }

    private class IconChooserListener implements ActionListener
    {
	@Override
	public void actionPerformed(ActionEvent e)
	{
	    JComboBox iconChooser = (JComboBox) e.getSource();
	    int index = iconChooser.getSelectedIndex();
	    Pin.this.icon = Pin.this.icons[index];
	    Pin.this.shapeChooserChoice = index;

	}
    }

    public void copyTo(Pin pin)
    {
	super.copyTo(pin);

	this.pinSize = pin.pinSize;
	this.horizontalOffset = pin.horizontalOffset;
	this.verticalOffset = pin.verticalOffset;
	this.icons = pin.icons.clone();
	this.shapeChooserChoice = pin.shapeChooserChoice;
    }
}

/*
 * <font size=+5><b>Title</b></font> <ul> <li><i>first entry</i> <li><u>second entry</u> <li><font color=blue>this is blue for some reason</font> </ul>
 */